package com.pjnkj.thunder.dagger.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pjnkj.thunder.dagger.common.Sheath;
import com.pjnkj.thunder.dagger.common.SpringUtils;
import com.pjnkj.thunder.entity.Widget;
import com.pjnkj.thunder.mapper.SqlMapper;
import com.pjnkj.thunder.mapper.WidgetMapper;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.*;
import java.util.stream.Collectors;

import static com.pjnkj.thunder.dagger.common.Arc.parameter4http;

public class WidgetService extends Sheath {

    public WidgetService(Object o) {
        String name = parameter4http(o, "name");
        WidgetMapper widgetMapper = SpringUtils.getBean("widgetMapper");

        QueryWrapper<Widget> qw = new QueryWrapper<Widget>();
        qw.eq("name", name);
        Widget widget = widgetMapper.selectOne(qw);
        if (widget != null) {
            HashMap carry = new HashMap();
            Map<String, Object> map0 = new HashMap<String, Object>() {{
                put("type", widget.getType());
                put("controller", widget.getController());
            }};
            SqlMapper sqlMapper = SpringUtils.getBean("sqlMapper");
            HashMap map1 = sqlMapper.getLineEx(name, "name", widget.getType());
            //先压入指定前端名称控件的数据库属性
            carry.putAll(map0);
            carry.putAll(map1);
            String controller = widget.getController();
            //如果填了初始化方法的control
            if (!controller.equals("")) {
                Object obj = SpringUtils.getBean(controller + "Controller");
                Class<?> aClass = obj.getClass();
                try {
                    Map<String, Object> o1 = (Map<String, Object>) o;

                    if (!widget.getMethod().equals("")) {
                        //如果填了方法名

                        List<Method> collect = Arrays.stream(aClass.getDeclaredMethods()).filter((e) -> e.getName().equals(widget.getMethod())).collect(Collectors.toList());
                        if (collect.size() > 0) {
                            //取反射到的第一个方法

                            Method method = collect.get(0);
                            Parameter[] parameters = method.getParameters();

                            HashMap re2 = new HashMap();

                            //若方法有参数 则用传参调整顺序执行
                            if (parameters != null && parameters.length > 0) {
                                //排除name和operation无用参数
                                Map<String, Object> o2 = o1.entrySet().stream()
                                        .filter((e) -> !e.getKey().equals("name") && !e.getKey().equals("operation"))
                                        .collect(Collectors.toMap(
                                                (e) -> (String) e.getKey(),
                                                (e) -> e.getValue()
                                        ));
                                ArrayList<String> par = new ArrayList<String>();
                                List<Parameter> collect1 = Arrays.stream(parameters).filter((e) -> o2.entrySet().stream().anyMatch((e2) -> {
                                    boolean equals = e.getName().equals(e2.getKey());
                                    if (equals) {
                                        par.add((String) e2.getValue());
                                    }
                                    return equals;

                                })).collect(Collectors.toList());
                                re2.put("carry", method.invoke(obj, (String[]) par.toArray(new String[par.size()])));
                                carry.putAll(re2);
                            } else {
                                //若方法无参数 则直接执行

                                re2.put("carry", method.invoke(obj));
                                carry.putAll(re2);
                            }
                        }

                    }

                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
            this.setObject(carry);
        }
    }

}
